#include "carnum.h"
#include <QtEndian>
#include <QtGlobal>

Carnum::Carnum(QImage &image) : image(image), manager(new QNetworkAccessManager(this))
{
    socket = new QTcpSocket(this);
    if (!classifier.load("D:\\APP\\Opencv\\sources\\data\\haarcascades\\haarcascade_russian_plate_number.xml")) {
        qDebug() << "classifier error !";
    }
    connect(socket, &QTcpSocket::readyRead, this, &Carnum::recvimage);
    connect(this, &Carnum::picDataReceived, this, &Carnum::get);

}

void Carnum::run()
{
    socket->connectToHost("192.168.2.56",8886);
    if(!socket->waitForConnected(1000)){
        qDebug() << "连接失败<Get Image port:8886>：" << socket->errorString();
    }

}

void Carnum::recvimage() {
    // 如果正在等待文件大小，则读取文件大小
    if (waitingForSize && socket->bytesAvailable() >= sizeof(uint64_t)) {
        QByteArray sizeData = socket->read(sizeof(uint64_t));
        fileSize = *reinterpret_cast<const uint64_t*>(sizeData.data());
        qDebug() << "Image size received:" << fileSize;
        waitingForSize = false;
    }

    // 如果已经接收到文件大小，则开始接收图像数据
    while (!waitingForSize && fileSize > 0 && socket->bytesAvailable() > 0) {
        qint64 bytesToRead = qMin<qint64>(fileSize, socket->bytesAvailable());
        QByteArray newData = socket->read(bytesToRead);
        jpegData.append(newData);
        fileSize -= bytesToRead;

        // 检查接收到结束
        if (fileSize <= 0) {
            qDebug() << "Image received completely.";
            if (image.loadFromData(jpegData)) {
                if (flag_emit) {
                    emit picDataReceived(image);
                    flag_emit = false;
                }
            } else {
                qDebug() << "Failed to load image from data.";
            }
            jpegData.clear();
            waitingForSize = true; // 准备接收下一张图片
            flag_emit = true;
        }
    }
}

void Carnum::get() {
    QTimer::singleShot(0, this, [this]() {
        // 确保image成员变量已经被正确初始化
        if (image.isNull()) {
            qDebug() << "Image is null";
            return;
        }
        QPixmap pixmap = QPixmap::fromImage(image);
        QImage img1 = pixmap.toImage();
        cv::Mat img(img1.height(), img1.width(), CV_8UC4, const_cast<uchar*>(img1.bits()), img1.bytesPerLine());

        if (img.empty()) {
            qDebug() << "img empty";
            return;
        }

        cvtColor(img, grayImage, COLOR_BGR2GRAY);
        classifier.detectMultiScale(img, plates);

        for (const Rect& plate : plates) {
            rectangle(img, plate, Scalar(0, 255, 0), 2);
        }

        if (plates.empty()) {
            //cout << "No plates detected." << endl;
             recognition();
        } else {
            cout << plates.size() << " plates detected." << endl;
            recognition();

        }
    });
}

void Carnum::recognition() {
    qDebug() << "recogintion ok";

    QByteArray bytearray;
    QBuffer buf(&bytearray);
    buf.open(QIODevice::WriteOnly);
    image.save(&buf, "JPG");
    QByteArray bytearrayData = bytearray.toBase64();
    if (bytearrayData.isEmpty()) {
        qDebug() << "PhotoToBase64 error";
        return;
    }
    QString urlEncoded = QUrl::toPercentEncoding(bytearrayData);

    QNetworkRequest request(QUrl("https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate?access_token=24.5f6e9fb4b227dfe27129bb60ddca6671.2592000.1736924206.282335-116654065"));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

    QUrlQuery postData;
    postData.addQueryItem("image", urlEncoded);

    qDebug() << "Sending request";
    QNetworkReply *reply = manager.post(request, postData.toString(QUrl::FullyEncoded).toUtf8());
    if (!reply) {
        qDebug() << "Network request not sent!";
        return;
    }

    connect(reply, &QNetworkReply::finished, this, &Carnum::handleRespose);
    qDebug() << "end recognition";
}

void Carnum::handleRespose() {
    qDebug() << "Network reply finished";
    QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());

    if (reply->error() == QNetworkReply::NoError) {
        QByteArray response = reply->readAll();
        qDebug() << response;
        QJsonDocument jsonDoc = QJsonDocument::fromJson(response);
        QJsonObject rootObj = jsonDoc.object();

        if (rootObj.contains("words_result")) {
            QJsonObject wordsResult = rootObj["words_result"].toObject();
            if (wordsResult.contains("number")) {
                QString plateNumberRaw = wordsResult["number"].toString();
                emit numDataReceived(plateNumberRaw);
            }
        }
    } else {
        QMessageBox::critical(nullptr, "错误", reply->errorString());
    }

    reply->deleteLater();
}

Carnum::~Carnum() {
    socket->disconnectFromHost();
    socket->deleteLater();
}
